// scene.hpp
//

#ifndef _SCENE_HPP
#define _SCENE_HPP

#include "base.hpp"

typedef size_t EntityFamilyID;

// Model
//
class Model
{
public:
  Model ( std::string mesh_path );

private:
  std::string mesh_path;
  wgl::Mesh mesh{};
  wgl::MeshBuffer mesh_buffer{};
};

// EntityFamily
//
struct EntityFamily
{
  EntityFamilyID id;
  std::string name;
};

// Entity
//
class Entity
{
public:
  Entity ( EntityFamilyID family,
           Model &model );

  EntityFamilyID get_family () { return family; }

  const glm::mat4 &matrix () { return transfo.matrix(); }
  
private:
  EntityFamilyID family;
  Model &model;
  wgl::Transfo transfo{};
};

// SceneManager
//
class SceneManager
{
public:
  EntityFamilyID register_entity_family ( std::string name );

  EntityFamilyID get_entity_family_id ( const std::string &name );
  
private:
  std::vector<EntityFamily> registered_entity_families;
};

// Scene
//
class Scene
{
public:
  Scene ( SceneManager &manager );

  SceneManager &get_manager () { return manager; }
  
  void register_model ( std::string name,
                        std::string obj_file );

  Entity *add_entity ( EntityFamilyID family,
                       std::string model_name );

  auto begin () { return entities.begin(); }
  auto end () { return entities.end(); }
  
private:
  static const std::string datadir;

  SceneManager &manager;
  
  std::unordered_map<std::string, Model *> models;
  std::vector<Entity *> entities;
};

inline const std::string Scene::datadir{DATADIR};

#endif
